package com.apptonelabs.android;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.style.RelativeSizeSpan;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnKeyListener;
import android.view.Window;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.apptonelabs.android.controller.PNREntryActivity;
import com.apptonelabs.android.controller.PNRListActivity;
import com.apptonelabs.android.controller.PNRStatusCrawller;
import com.apptonelabs.android.model.PNREntryList;
import com.apptonelabs.android.model.PNRStatus;
import com.apptonelabs.android.model.PNRStatusList;
import com.apptonelabs.android.model.PNRType;
import com.apptonelabs.android.model.PassengerDetails;
import com.apptonelabs.android.util.TimeUtil;

public class MainActivity extends Activity {
	private Button futureBt = null;
	private Button todayBt = null;
	private Button pastBt = null;
	private Button pnrSubmitBt = null;
	private TextView errMsgTV = null;
	private EditText pnrET = null;

	private static Context context = null;

	private ProgressDialog progressBar;
	private int progressBarStatus = 0;
	private Handler progressBarbHandler = new Handler();
	private PNRStatus pnrStatus = null;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		// No title bar
		this.requestWindowFeature(Window.FEATURE_NO_TITLE);

		setContentView(R.layout.main);

		// Load Context
		context = this.getApplicationContext();

		this.futureBt = (Button) this.findViewById(R.id.futureBt);
		this.todayBt = (Button) this.findViewById(R.id.todayBt);
		this.pastBt = (Button) this.findViewById(R.id.pastBt);
		this.pnrSubmitBt = (Button) this.findViewById(R.id.pnrBt);
		this.errMsgTV = (TextView) this.findViewById(R.id.errMsgTV);
		this.pnrET = (EditText) this.findViewById(R.id.pnrET);

		// Update Counts
		this.updateCounts();

		LinearLayout addLH = (LinearLayout) findViewById(R.id.buttonLH);
		addLH.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				Intent intent = new Intent(context, MainActivity.class);
				intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
				intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
				intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

				context.startActivity(intent);
			}
		});

		LinearLayout addL = (LinearLayout) findViewById(R.id.addL);
		addL.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri
						.parse("http://arogyavarshini.in"));
				startActivity(browserIntent);
			}
		});

		this.futureBt.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View arg0) {
				// speakOut();
				// startVoiceRecognitionActivity();
				listPNR(PNRType.FUTURE);
				//test();
			}
		});

		this.futureBt.setOnKeyListener(new OnKeyListener() {

			@Override
			public boolean onKey(View arg0, int arg1, KeyEvent arg2) {
				System.out.println("Future Button Entered");
				listPNR(PNRType.FUTURE);
				return false;
			}
		});

		this.todayBt.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View arg0) {
				System.out.println("Today Button Clicked");
				listPNR(PNRType.TODAY);
			}
		});

		this.todayBt.setOnKeyListener(new OnKeyListener() {

			@Override
			public boolean onKey(View arg0, int arg1, KeyEvent arg2) {
				System.out.println("Today Button Entered");
				listPNR(PNRType.TODAY);
				return false;
			}
		});

		this.pastBt.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View arg0) {
				System.out.println("Past Button Clicked");
				listPNR(PNRType.PAST);
			}
		});

		this.pastBt.setOnKeyListener(new OnKeyListener() {

			@Override
			public boolean onKey(View arg0, int arg1, KeyEvent arg2) {
				System.out.println("Past Button Entered");
				listPNR(PNRType.PAST);
				return false;
			}
		});

		this.pnrSubmitBt.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View view) {
				Button pnrSubmitBt = (Button) view.findViewById(R.id.pnrBt);
				pnrSubmitBt.setEnabled(false);
				// processSubmitAction();

				// create and display a new ProgressBarDialog
				progressBar = new ProgressDialog(view.getContext());
				progressBar.setCancelable(true);
				progressBar.setMessage("Processing ...");
				progressBar.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
				progressBar.setProgress(0);
				progressBar.setMax(100);
				progressBar.show();
				progressBarStatus = 10;

				Thread t = new Thread(new Runnable() {
					public void run() {
						while (progressBarStatus < 100) {
							// process some tasks
							pnrStatus = getPNRStatus();

							// Update the progress bar
							progressBarbHandler.post(new Runnable() {
								public void run() {
									progressBar.setProgress(progressBarStatus);
								}
							});
						}
						// if the file is downloaded,
						if (progressBarStatus >= 100) {
							// sleep 2 seconds, so that you can see the 100%
							try {
								Thread.sleep(2000);
							} catch (InterruptedException e) {
								e.printStackTrace();
							}
							// and then close the progressbar dialog
							progressBarStatus = 100;
							progressBar.dismiss();
						}
					}
				});
				
				t.start();
				try {
					t.join();
				} catch (InterruptedException e) {
				}

				showPNR();
				pnrSubmitBt.setEnabled(true);
			}
		});

		this.pnrSubmitBt.setOnKeyListener(new OnKeyListener() {

			@Override
			public boolean onKey(View arg0, int arg1, KeyEvent arg2) {
				return true;
			}
		});
	}
	
	private void showPNR() {
		Bundle bundle = new Bundle();
		List<String> list = new ArrayList<String>();
		PNREntryList obj = new PNREntryList();
		
		try {
			Intent to = null;
			if (pnrStatus != null) {
				errMsgTV.setText("");

				list.add("Title");
				list.add("<b>PNR Number		:</b> " + pnrStatus.getPnr());
				list.add("<b>Journey Date		:</b> " + pnrStatus.getTrainDetails().getBoardingDate());
				list.add("<b>Train number	:</b> " + pnrStatus.getTrainDetails().getNumber().substring(1,
						pnrStatus.getTrainDetails().getNumber().length()));
				list.add("<b>Current status	:</b> " + pnrStatus.getPassengerDetails().get(0).getCurrentStatus());
				list.add("<b>Train from		:</b> " + pnrStatus.getTrainDetails().getFrom());
				list.add("<b>Boradring point	:</b> " + pnrStatus.getTrainDetails().getBoardingPoint());
				list.add("<b>Train to			:</b> " + pnrStatus.getTrainDetails().getTo());
				list.add("<b>Reservation up to:</b> " + pnrStatus.getTrainDetails().getReservedUpto());
				list.add("<b>Chart Status:</b> " + pnrStatus.getTrainDetails().getChatStatus());
				list.add("<b>Passengers		:</b> ");
				for(PassengerDetails pd : pnrStatus.getPassengerDetails()) {
					list.add(pd.getName() + " " + pd.getBookingStatus() + " " + pd.getCurrentStatus());
				}
				
				obj.setList(list);
				
				bundle.putSerializable("pnrlist", obj);
				bundle.putSerializable("pnrlisttype", PNRType.PNR);

				to = new Intent(this, PNREntryActivity.class);
				to.putExtras(bundle);

				startActivity(to);
			} else {
				progressBar.dismiss();
				errMsgTV.setText("Error prcessing PNR(2). Please try again.");
			}
		} catch (Throwable e) {
			progressBar.dismiss();
			errMsgTV.setText("Error prcessing PNR(3). Please try again.");
		}
	}

	private void updateCounts() {
		// DB Handler
		DatabaseHandler db = new DatabaseHandler(this);

		long pC = 0;
		try {
			pC = db.getPastPNRCount();
		} catch (Exception e) {
			e.printStackTrace();
		}
		//this.todayBt.setText("Today #" + pC);
		this.pastBt.setText(getSpannable(" Past  ", Long.toString(pC)));
		
		long tC = 0;
		try {
			tC = db.getTodayPNRCount();
		} catch (Exception e) {
			e.printStackTrace();
		}
		this.todayBt.setText(getSpannable(" Today", Long.toString(tC)));
		//this.todayBt.setText("Today #" + tC);

		long fC = 0;
		try {
			fC = db.getFuturePNRCount();
		} catch (Exception e) {
			e.printStackTrace();
		}
		this.futureBt.setText(getSpannable("Future", Long.toString(fC)));
		//this.futureBt.setText("Future #" + fC);
	}

	private void listPNR(PNRType type) {
		DatabaseHandler db = new DatabaseHandler(this);
		List<PNRStatus> list = db.getPNRList(type);

		try {
			Intent to = new Intent(this, PNRListActivity.class);
			Bundle bundle = new Bundle();
			PNRStatusList obj = new PNRStatusList();
			obj.setList(list);
			bundle.putSerializable("pnrlist", obj);
			bundle.putSerializable("pnrlisttype", type);
			to.putExtras(bundle);
			startActivity(to);
		} catch (Throwable e) {
			e.printStackTrace();
		}
	}

	/**
	 * Get the Status of the PNR and Navigate to PNR Details or Error
	 * 
	 * @param pnr
	 * @return
	 */
	private PNRStatus getPNRStatus() {
		// check the PNR number validity
		// All should be digits and length=10
		String pnr = this.pnrET.getText().toString();

		// check the Connectivity
		if (!this.isNetworkAvailable()) {
			this.errMsgTV.setText("No Network connectivity");
			return null;
		}

		progressBarStatus = 20;

		// Proceed further
		PNRStatus pnrStatus = null;

		// Connect to the Server and Get the PNR status
		try {
			String pnr1 = pnr; // "1154177041";
			String reqStr = "lccp_pnrno1=" + pnr1 + "&lccp_cap_val=13667&lccp_capinp_val=13667&submitpnr=Get+Status";
			PNRStatusCrawller check = new PNRStatusCrawller();
			StringBuffer data = check.getPNRResponse(reqStr, "http://www.indianrail.gov.in/cgi_bin/inet_pnstat_cgi_29055.cgi");
			if (data != null) {
				pnrStatus = check.parseHtml(data);
				if(pnrStatus != null) {
					pnrStatus.setPnr(pnr1);
				}
			} else {
				// error
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		progressBarStatus = 40;

		if (pnrStatus != null) {
			// Save to DB before navigation
			// preprocess it
			pnrStatus.setPnr(pnr);
			try {
				pnrStatus.setDoj(TimeUtil.date2long(pnrStatus.getTrainDetails()
						.getBoardingDate()));
			} catch (ParseException e1) {
				// ignore
			}

			DatabaseHandler db = new DatabaseHandler(this);
			try {
				db.saveOrUpdatePNR(pnrStatus);
			} catch (Throwable e) {
				// ignore
			}
		}

		progressBarStatus = 100;

		return pnrStatus;
	}

	public boolean isNetworkAvailable() {
		ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
		NetworkInfo networkInfo = cm.getActiveNetworkInfo();
		// if no network is available networkInfo will be null, otherwise check
		// if we are connected
		if (networkInfo != null && networkInfo.isConnected()) {
			return true;
		}
		return false;
	}

	private int group1Id = 1;
	private int clearAllData = Menu.FIRST;

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Build the Menu
		menu.add(group1Id, clearAllData, clearAllData, "Erase All Data");

		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {

		switch (item.getItemId()) {

		case 1:
			try {
				DatabaseHandler db = new DatabaseHandler(this);
				db.eraseAllData();
				Toast msg = Toast.makeText(MainActivity.this,
						"All the Data Erased.", Toast.LENGTH_LONG);
				msg.show();
			} catch (Exception e) {
				Toast msg = Toast.makeText(MainActivity.this,
						"Not able to erase data.", Toast.LENGTH_LONG);
				msg.show();
			}
			return true;

		default:
			break;

		}
		return super.onOptionsItemSelected(item);
	}

	public void launchRingDialog(View view) {
		final ProgressDialog ringProgressDialog = ProgressDialog.show(
				MainActivity.this, "Please wait ...", "Downloading Image ...",
				true);
		ringProgressDialog.setCancelable(true);
		new Thread(new Runnable() {
			@Override
			public void run() {
				try {
					// Here you should write your time consuming task...
					// Let the progress ring for 10 seconds...
					Thread.sleep(10000);
				} catch (Exception e) {

				}
				ringProgressDialog.dismiss();
			}
		}).start();
	}

	@SuppressWarnings("unused")
	private void test() {
		for(long p=4603611500L; p<4603611599L; p++) {
			// Proceed further
			PNRStatus pnrStatus = null;
	
			// Connect to the Server and Get the PNR status
			try {
				String pnr1 = Long.toString(p);
				String reqStr = "lccp_pnrno1=" + pnr1 + "&submitpnr=Get+Status";
				PNRStatusCrawller check = new PNRStatusCrawller();
				StringBuffer data = check
						.getPNRResponse(reqStr,
								"http://www.indianrail.gov.in/cgi_bin/inet_pnrstat_cgi.cgi");
				if (data != null) {
					pnrStatus = check.parseHtml(data);
				}
				
				if (pnrStatus != null) {
					// Save to DB before navigation
					// preprocess it
					pnrStatus.setPnr(pnr1);
					try {
						pnrStatus.setDoj(TimeUtil.date2long(pnrStatus.getTrainDetails()
								.getBoardingDate()));
					} catch (ParseException e1) {
						// ignore
					}

					DatabaseHandler db = new DatabaseHandler(this);
					try {
						db.saveOrUpdatePNR(pnrStatus);
					} catch (Throwable e) {
						// ignore
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
	
	private Spannable getSpannable(String s1, String s2) {
		int n = s1.length();
		int m = s2.length();

		Spannable span = new SpannableString(s1 + "\n" +  s2);
		span.setSpan(new RelativeSizeSpan(1f), 0, n, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
		span.setSpan(new RelativeSizeSpan(1.5f), n, (n+m+1), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

		return span;
	}

}
